package com.changsideal.entity;

import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.changsideal.tool.Constant;
import com.changsideal.util.PropertyUtil;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @ClassName P
 * @Description TODO
 * @Author Create by Chansideal.Haosc
 * @Date 2019/6/14 16:57
 * @Version 1.2
 **/
@Getter
@Slf4j
public final class P implements AutoCloseable {
    private String endpoint;
    private String access_key_id;
    private String secret_key;
    private String bucket;
    private String versioned_bucket;
    private String object;
    private String public_endpoint;
    private String config_use;
    private String namespace;
    private Regions region;
    private static final Regions DEFAULT_REGIONS = Regions.AP_NORTHEAST_1;
    private static final ThreadLocal<P> PCACHE = new ThreadLocal<>();

    private P(PBuilder builder) {
        this.endpoint = builder.endpoint;
        this.access_key_id = builder.access_key_id;
        this.secret_key = builder.secret_key;
        this.bucket = builder.bucket;
        this.versioned_bucket = builder.versioned_bucket;
        this.object = builder.object;
        this.public_endpoint = builder.public_endpoint;
        this.config_use = builder.config_use;
        this.namespace = builder.namespace;
        this.region = builder.region;
    }

    private P() {
    }

    @Getter
    public static class PBuilder {
        private String endpoint;
        private String access_key_id;
        private String secret_key;
        private String bucket;
        private String versioned_bucket;
        private String object;
        private String public_endpoint;
        private String config_use;
        private String namespace;
        private Regions region;

        public PBuilder() {
        }

        public PBuilder setEndPoint(String endpoint) {
            this.endpoint = endpoint;
            return this;
        }

        public PBuilder setAccessKeyId(String access_key_id) {
            this.access_key_id = access_key_id;
            return this;
        }

        public PBuilder setSecretKey(String secret_key) {
            this.secret_key = secret_key;
            return this;
        }

        public PBuilder setBucket(String bucket) {
            this.bucket = bucket;
            return this;
        }

        public PBuilder setVersionedBucket(String versioned_bucket) {
            this.versioned_bucket = versioned_bucket;
            return this;
        }

        public PBuilder setObject(String object) {
            this.object = object;
            return this;
        }

        public PBuilder setPublicEndPoint(String public_endpoint) {
            this.public_endpoint = public_endpoint;
            return this;
        }

        public PBuilder setConfigUse(String config_use) {
            this.config_use = config_use;
            return this;
        }

        public PBuilder setNamespace(String namespace) {
            this.namespace = namespace;
            return this;
        }

        public PBuilder setRegion(Regions region) {
            this.region = region;
            return this;
        }

        public P build() {
            P p = new P(this);
            if (null != PCACHE.get()) {
                remove();
            }
            PCACHE.set(p);
            return p;
        }
    }

    private static String getPropertiesConfig() {
        String configResult = null;
        Properties properties = PropertyUtil.getProperty(Constant.AWS_CONFIG_NAME);
        if (properties != null) {
            configResult = PropertyUtil.getConfigString(properties, Constant.AWS_CONFIG_OPEN);
        }
        return configResult;
    }

    public static P build() {
        P p = null;
        String config = getPropertiesConfig();
        if (StringUtils.isNotEmpty(config)) {
            if (Constant.LOCAL_CONFIG_ON.equals(config)) {
                try {
                    p = createP();
                } catch (IllegalAccessException | InstantiationException e) {
                    log.error("配置有误，请检查！" + e.getMessage(), e);
                }
            }
        }
        return p;
    }
    
    public static P.PBuilder builder(){
    	return new P.PBuilder();
    }
    
    public static P builderSimple(String ACCESS_KEY, String SECRET_KEY, String ENDPOINT) {
    	return builderSimple(ACCESS_KEY, SECRET_KEY, ENDPOINT, DEFAULT_REGIONS);
    }
    
    public static P builderSimple(String ACCESS_KEY, String SECRET_KEY, 
    								String ENDPOINT, Regions REGIONS) {
    	return builder().setAccessKeyId(ACCESS_KEY)
    			.setSecretKey(SECRET_KEY).setEndPoint(ENDPOINT)
    			.setRegion(REGIONS).build();
    }

    private static P createP() throws IllegalAccessException, InstantiationException {
        P p = new P();
        Properties properties = PropertyUtil.getProperty(Constant.AWS_CONFIG_NAME);
        List<Field> fields = new ArrayList<>(Arrays.asList(P.class.getDeclaredFields()));
        for (Map.Entry<Object, Object> entry : properties.entrySet()) {
            String key = (String) entry.getKey();
            String values = (String) entry.getValue();
            for (Field field : fields) {
                if (key.equals(field.getName())) {
                    field.set(p, values);
                }
            }
        }
        PCACHE.set(p);
        return p;
    }

    public static P get() {
        return PCACHE.get();
    }

    public static void remove() {
        if (null != PCACHE.get()) {
            PCACHE.remove();
        }
    }

    @Override
    public void close() throws Exception {
        if (null != PCACHE.get()) {
            PCACHE.remove();
        }
    }

    @Deprecated
    void init() {
        String config = getPropertiesConfig();
        if (StringUtils.isNotEmpty(config)) {
            if (Constant.LOCAL_CONFIG_ON.equals(config)) {
                try {
                    createP();
                } catch (IllegalAccessException | InstantiationException e) {
                    e.printStackTrace();
                }
            }
        } else {
            log.error("配置有误，请检查！");
        }
    }

    @Override
    public String toString() {
        return "P{" +
                "endpoint='" + endpoint + '\'' +
                ", access_key_id='" + access_key_id + '\'' +
                ", secret_key='" + secret_key + '\'' +
                ", bucket='" + bucket + '\'' +
                ", versioned_bucket='" + versioned_bucket + '\'' +
                ", object='" + object + '\'' +
                ", public_endpoint='" + public_endpoint + '\'' +
                ", config_use='" + config_use + '\'' +
                ", namespace='" + namespace + '\'' +
                ", region='" + region + '\'' +
                '}';
    }
}